{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "d6029042-a5bc-44dd-98be-882750f4ae9c",
   "metadata": {},
   "source": [
    "# Exercise 2"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a801d2df-6e3e-494f-83f0-bdeb8ac40e51",
   "metadata": {},
   "source": [
    "Recall that the *Geometric Brownian Motion* (GBM) model of stock prices is defined by\n",
    "$$dS_t = \\mu S_t dt + \\sigma S_t dW_t$$\n",
    "and it has solution\n",
    "\n",
    "$$\n",
    "S_t = S_0 \\exp\\left[\n",
    "\\left(\n",
    "\\mu - \\frac{\\sigma^2}{2}\n",
    "\\right) t\n",
    "+ \\sigma W_t\n",
    "\\right]\n",
    "$$\n",
    "## Question 1 ## \n",
    "Simulate 100 GBM sample paths, each of which has length $201$ and $S_0 = 1, \\mu=0.08, \\sigma=0.06$. Take the time step as $\\Delta t = 1/200$."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d004ec3-f25f-47d0-a648-4eb4f8b0803f",
   "metadata": {},
   "source": [
    "**Hint**\n",
    "1. The 200 steps of each path corresponds to $t=0.005\\times1, 0.005\\times2, \\dots, 0.005\\times200$.\n",
    "2. calculate $\\mu + \\frac{\\sigma^2}{2} = 0.08 + \\frac{0.06^2}{2} = 0.818$.\n",
    "3. simulate $\\left(\\mu - \\frac{\\sigma^2}{2}\\right) t$ as a sequence $A$ of 200 items\n",
    "   - $A_1 = 0.818 \\times 1 \\times 0.05$\n",
    "   - $A_2 = 0.818 \\times 2 \\times 0.005$\n",
    "   - ...\n",
    "   - $A_{200} = 0.818 \\times 200 \\times 0.005$\n",
    "4. simulate $W_t$ as another sequence of 200 items:\n",
    "   1. simulate 200 standard normal random variables $x_1, x_2, \\dots, x_{200}$ using scipy.stats.norm.rvs(size=200)\n",
    "   2. Generate the $W_t$ sequence as\n",
    "      - $W_1 = \\sqrt{\\Delta t} \\times x_1$\n",
    "      - $W_2 = \\sqrt{\\Delta t} \\times (x_1 + x_2)$\n",
    "      - ...\n",
    "      - $W_{200} = \\sqrt{\\Delta t} \\times (x_1 + x_2 + \\cdots + x_{200})$\n",
    "\n",
    "      Note: $\\sqrt{\\Delta t} = \\sqrt{0.005} \\approx 0.0707$. Use numpy.sqrt\n",
    "   3. Use $\\sigma = 0.06, S_0 = 1$ and simulate $S_1, S_2, \\dots, S_{200}$ as\n",
    "      - $S_1 = \\exp(A_1 + 0.06\\times W_1)$\n",
    "      - $S_2 = \\exp(A_2 + 0.06\\times W_2)$\n",
    "      - ...\n",
    "      - $S_{200} = \\exp(A_{200} + 0.06\\times W_{200})$\n",
    "        \n",
    "       Use numpy.exp for the $\\exp$ function.\n",
    "    4. Assign $S_0 = 1$.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a38cc785-2b2e-4a05-b257-027d0267afdd",
   "metadata": {},
   "source": [
    "**Solution**:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "ec53ed9a-3364-456c-b8e5-05b1d0837ce5",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "from scipy.stats import norm\n",
    "\n",
    "N = 200\n",
    "K = 100\n",
    "S0 = 1\n",
    "mu = 0.08\n",
    "sigma = 0.06\n",
    "Dt = 1/N\n",
    "sqrt_Dt = 1/np.sqrt(N)\n",
    "\n",
    "traj = np.full((N+1, K), np.nan)\n",
    "# Your code goes here"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b73b62ef-6f9a-419b-8a4c-f89ee081aa4f",
   "metadata": {},
   "source": [
    "## Question 2 ##\n",
    "Calibrate a GBM model to each of the 100 sample paths.\n",
    "\n",
    "**Hint**\n",
    "Suppose we are calibrating the model to the sample path $S_0, S_1, S_2, \\dots, S_{200}$.\n",
    "1. Compute the sequence\n",
    "   - $a_1 = \\ln S_1 - \\ln S_0$\n",
    "   - $a_2 = \\ln S_2 - \\ln S_1$\n",
    "   - ...\n",
    "   - $a_{200} = \\ln S_{200} - \\ln S_{199}$\n",
    "\n",
    "    Use numpy.log for the $\\ln$ function.\n",
    "2. Compute the mean and the standard deviation of $a_1, a_2, \\dots, a_{200}$. Call the mean $\\bar a$ and the standard deviation $\\hat a$. Use bootstrapping for this purpose - simply adding up all the $a$'s and diving the sum by 200 will just give us $(\\ln S_{200} - \\ln S_0)/200$. We want to use all the $a$'s! Follow these steps:\n",
    "   1. randomly choose, with replacement, 100 items from $a_1, a_2, \\dots, a_{200}$. Use numpy.random.Generator.choice for this. Call the selected numbers $b_1, b_2, \\dots, b_{100}$. This is a bootstrap sample. Call it bootstrap sample 1.\n",
    "   2. calculate the average of bootstrap sample 1 and call the result $m_1$: $m_1 = (b_1 + b_2 + \\cdots + b_{100})/100$.\n",
    "   3. calculate the average of the squares of bootstrap sample 1 and call the result $q_1$: $q_1 = (b_1^2 + b_2^2 + \\cdots + b_{100}^2)/100$.\n",
    "   4. In the same way as we created bootstrap sample 1, create bootstrap sample 2, 3, 4, ..., 10.\n",
    "   5. Calculate the average of each of the bootstrap samples and the average of the squares of each of the samples. Call them $m_2, m_3, \\dots, m_{10}$ and $q_2, q_3, \\dots, q_{10}$\n",
    "3. Calculate $\\bar a$ as\n",
    "   $$\\bar a = {m_1 + m_2 + \\cdots + m_{10} \\over 10}$$\n",
    "4. Calculate $\\hat a$ as\n",
    "   $$\\hat a = \\sqrt{{q_1 + q_2 + \\cdots + q_{10} \\over 10} - \\bar{a}^2}$$\n",
    "5. Now estimate the model parameter $\\sigma$ as\n",
    "   $$\\sigma = \\frac{\\hat a}{\\sqrt{\\Delta t}}$$\n",
    "6. Estimate the model parameter $\\mu$ as\n",
    "   $$\\mu = \\frac{\\bar{a}}{\\Delta t} + \\frac{\\hat{a}^2}{2\\times\\Delta t}$$\n",
    "7. Now the model parameters $\\mu$ and $\\sigma$ have been estimated, model calibration is complete."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "49b770d6-92cf-4844-ad22-c7bcbcebdedf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n",
      "model parameters: nan, nan\n"
     ]
    }
   ],
   "source": [
    "class GBM:\n",
    "    def __init__(self):\n",
    "        self.mu = np.nan;\n",
    "        self.sigma = np.nan;\n",
    "        self.rng = np.random.default_rng()\n",
    "        \n",
    "    def calibrate(self, trajectory, Dt):\n",
    "        # Your code goes here\n",
    "        pass\n",
    "\n",
    "for i in range(K):\n",
    "    model = GBM();\n",
    "    model.calibrate(traj[:, i], Dt);\n",
    "    print(F\"model parameters: {model.mu}, {model.sigma}\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "880a7eb1-dbfe-4494-baf2-dfce444a64e1",
   "metadata": {},
   "source": [
    "## Question 3 ##\n",
    "calibrate a GBM model to the provided S&P500 series."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b6016fe5-1b37-44a0-9773-6a9aeb27331f",
   "metadata": {},
   "source": [
    "**Solutions**: We first read the prices data into an array and then use GBM.calibrate to calibrate the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "babea0b9-44d6-43d7-a1ba-29d4f2c6be14",
   "metadata": {},
   "outputs": [],
   "source": [
    "import csv\n",
    "from contextlib import closing\n",
    "\n",
    "# Your code goes here"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
